package com.xunlai.infra.permission.manager.web.service.impl;

import com.xunlai.infra.permission.common.exception.DataNotExistException;
import com.xunlai.infra.permission.common.exception.PermissionBusinessException;
import com.xunlai.infra.permission.manager.web.converter.DepartmentConverter;
import com.xunlai.infra.permission.manager.web.service.DepartmentService;
import com.xunlai.infra.permission.manager.web.vo.department.CreateDepartmentReqVo;
import com.xunlai.infra.permission.manager.web.vo.department.DepartmentListVo;
import com.xunlai.infra.permission.manager.web.vo.department.QueryDepartmentVo;
import com.xunlai.infra.permission.manager.web.vo.department.UpdateDepartmentReqVo;
import com.xunlai.infra.permission.storage.entity.Department;
import com.xunlai.infra.permission.storage.repository.DepartmentRepository;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import static com.xunlai.infra.permission.manager.web.converter.DepartmentConverter.INSTANCE;

/**
 * @author liang
 * @date 12/11/22 9:33 PM
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DepartmentServiceImpl implements DepartmentService {

    private DepartmentRepository departmentRepository;

    @Override
    public Long createDepartment(CreateDepartmentReqVo createDepartmentReqVo) {
        Department save = departmentRepository.save(INSTANCE.convertCreateReq2Department(createDepartmentReqVo));
        return save.getId();
    }

    @Override
    public List<Long> createDepartment(List<CreateDepartmentReqVo> createDepartmentReqVo) {
        if(CollectionUtils.isEmpty(createDepartmentReqVo)){
            return Collections.emptyList();
        }
        List<Department> departments = createDepartmentReqVo.stream().map(INSTANCE::convertCreateReq2Department).toList();
        Iterable<Department> saveAll = departmentRepository.saveAll(departments);
        return StreamSupport.stream(saveAll.spliterator(),false).map(Department::getId).toList();
    }

    @Override
    public List<DepartmentListVo> listDepartment(QueryDepartmentVo queryDepartmentVo) {
        Department department = INSTANCE.convertQueryReqVo2Department(queryDepartmentVo);
        Iterable<Department> all = departmentRepository.findAll(Example.of(
                department,
                ExampleMatcher.matching()
                        .withMatcher("departName", g -> g.caseSensitive().contains())
                        .withMatcher("departCode", g -> g.caseSensitive().exact())
        ));
        return StreamSupport.stream(all.spliterator(), false).map(INSTANCE::convert2ListVo).toList();
    }

    @Override
    public void updateDepartment(UpdateDepartmentReqVo updateDepartmentReqVo) throws PermissionBusinessException {
        Long id = updateDepartmentReqVo.getId();
        Optional<Department> departmentOptional = departmentRepository.findById(id);
        if(departmentOptional.isEmpty()){
            throw new DataNotExistException("需要修改的部门不存在");
        }
        Department department = departmentOptional.get();
        if(updateDepartmentReqVo.getDepartName() != null){
            department.setDepartName(updateDepartmentReqVo.getDepartName());
        }
        if(updateDepartmentReqVo.getManager() != null){
            department.setManager(updateDepartmentReqVo.getManager());
        }
        if(updateDepartmentReqVo.getSort() != null){
            department.setSort(updateDepartmentReqVo.getSort());
        }
        if(updateDepartmentReqVo.getParentId() != null){
            department.setParentId(updateDepartmentReqVo.getParentId());
        }
        departmentRepository.save(department);
    }

    @Override
    public boolean deleteDepartment(Long id, boolean recursive) {
        if(recursive){
            //TODO 把部门及子部门下的人移到该部门的父部门
            //TODO 删除子部门
        }else {
            //TODO 把部门下的人及子部门移到该部门的父部门
        }
        departmentRepository.deleteById(id);
        return true;
    }

    @Autowired
    public void setDepartmentRepository(DepartmentRepository departmentRepository) {
        this.departmentRepository = departmentRepository;
    }
}
